package de.zainodis.triplog.ui.fragment;

import android.app.Fragment;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import de.zainodis.triplog.R;
import de.zainodis.triplog.data.DataProvider;
import de.zainodis.triplog.data.TripEntry;
import de.zainodis.triplog.ui.DashboardActivity;
import de.zainodis.triplog.ui.ImageViewer;
import de.zainodis.triplog.ui.task.GalleryLoader;

/**
 * Created by fzarrai on 10/8/2014.
 */
public class GalleryPreviewFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

    private static final String TAG = "GalleryPreviewFragment";
    private static final int GALLERY_LOADER_ID = 1;
    private CursorPagerAdapter galleryAdapter;
    private ViewPager pager;

    private View.OnClickListener onPageClickedListener;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        onPageClickedListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                long id = galleryAdapter.getIdForCurrentItem();
                if (id > 0) {
                    //Show image fullscreen
                    Intent intent = new Intent(getActivity(), ImageViewer.class);
                    intent.putExtra(ImageViewer.IMAGE_ID, id);
                    getActivity().startActivity(intent);
                } else {
                    Log.w(TAG, "Database id of selected image is invalid.");
                    Toast.makeText(getActivity(), getString(R.string.invalid_image_id), Toast.LENGTH_LONG).show();
                }
            }
        };

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_gallery_preview, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        pager = (ViewPager) view.findViewById(R.id.fragment_gallery_preview_pager);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        onPageClickedListener = null;
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        TripEntry trip = DataProvider.getCurrentTrip();
        if (trip == null) {
            return null;
        } else {
            return new GalleryLoader(getActivity(), trip);
        }
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        if (galleryAdapter == null) {
            galleryAdapter = new CursorPagerAdapter(getActivity().getLayoutInflater(), getActivity(), data);
        }

        View view = getView().findViewById(R.id.fragment_gallery_preview_pager);
        if (view != null) {
            if (data.getCount() > 0) {
                view.setVisibility(View.VISIBLE);
            } else {
                view.setVisibility(View.GONE);
            }
        }

        //Update gallery view adapter
        galleryAdapter.swapCursor(data);
        //Update adapter of viewpager
        pager.setAdapter(galleryAdapter);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        //Reset gallery view adapter
        galleryAdapter.swapCursor(null);
    }

    public void onUpdate(DashboardActivity dashboardActivity) {
        getLoaderManager().restartLoader(GALLERY_LOADER_ID, null, this);
    }

    private class CursorPagerAdapter extends PagerAdapter {

        private final LayoutInflater inflater;
        private Cursor cursor;
        private Context context;

        public CursorPagerAdapter(LayoutInflater inflater, Context context, Cursor cursor) {
            this.inflater = inflater;
            this.cursor = cursor;
            this.context = context;
        }

        @Override
        public int getCount() {
            if (cursor == null) {
                //TODO show a message if there are no items
                return 0;
            } else {
                return cursor.getCount();
            }
        }

        public Object instantiateItem(ViewGroup collection, int position) {
            if (cursor == null) {
                return null;
            }
            if (cursor.moveToPosition(position)) {
                //TODO consider adding delete on long press
                ImageView view = (ImageView) inflater.inflate(R.layout.widget_imageview, null);
                long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media._ID));
                //TODO this should be done in the background and the thumbnails are too small
                Bitmap image = MediaStore.Images.Thumbnails.getThumbnail(context.getContentResolver(),
                        id, MediaStore.Images.Thumbnails.MINI_KIND, null);
                view.setImageBitmap(image);
                collection.addView(view);

                //We'll use this to track clicks on the image
                view.setOnClickListener(onPageClickedListener);

                return view;
            } else {
                Log.e(TAG, "Failed to advance cursor to position " + position);
                return null;
            }
        }

        /**
         * @return database id for the current image that can be used to retrieve it from MediaStore. -1 if there is none or the cursor is currently not set.
         */
        protected long getIdForCurrentItem() {
            if (cursor != null) {
                long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media._ID));
                return id;
            }
            return -1;
        }

        public Cursor getCursor() {
            return cursor;
        }

        public void swapCursor(Cursor c) {
            if (cursor == c) {
                return;
            }
            //Close the old cursor
            closeCursor();

            this.cursor = c;
            notifyDataSetChanged();
        }

        protected void closeCursor() {
            if (cursor != null) {
                cursor.close();
                cursor = null;
            }
        }

        @Override
        public void destroyItem(ViewGroup collection, int position,
                                Object view) {
            ((ViewPager) collection).removeView((ImageView) view);
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == ((ImageView) object);
        }

    }
}
